package com.readfeed.app;

import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.app.Activity;
import android.app.DialogFragment;
import android.os.AsyncTask;
import com.readfeed.app.data.FeedsAdapter;
import com.readfeed.app.fragment.ErrorDialogFragment;
import com.readfeed.app.fragment.ProgressDialogFragment;
import com.readfeed.app.model.Channel;
import com.readfeed.app.model.Feed;
import com.readfeed.app.utils.Utilities;

public class UpdateChannelTask extends AsyncTask<Void, Void, Void> {

	private Activity mContext;
	private long mDiscardPeriod;
	private long mUpdatePeriod;
	private long mChannelId;
	private String mChannelUrl;
	private FeedsAdapter mFeedAdapter;
	private boolean mIsConnected;
	private long mChannelLastUpdate;
	private Exception ex = null;
	
	public UpdateChannelTask(Activity activity, long discardPeriod, long updatePeriod,long channelLastUpdate,
			long channelId, String channelUrl, FeedsAdapter feedsAdapter, boolean isConnected){
		this.mContext = activity;
		this.mDiscardPeriod = discardPeriod;
		this.mUpdatePeriod = updatePeriod;
		this.mChannelLastUpdate = channelLastUpdate;
		this.mChannelId = channelId;
		this.mChannelUrl = channelUrl;
		this.mFeedAdapter = feedsAdapter;
		this.mIsConnected = isConnected;
	}
	
	@Override
	protected void onPreExecute() {
		DialogFragment progressDialog = ProgressDialogFragment.newInstance(R.string.update_channel_message);
		progressDialog.show(mContext.getFragmentManager(), Utilities.PROGRESS_DIALOG_TAG);
	}
			
	@Override
	protected Void doInBackground(Void... params) {
		ChannelParser parser = new ChannelParser();			
		try{
			if (mDiscardPeriod != -1) {
				List<Feed> feedsToDiscard = mFeedAdapter.getFeedsToDiscard(mDiscardPeriod, mChannelId);
				if (feedsToDiscard.size() > 0) {
					mFeedAdapter.deleteFeeds(feedsToDiscard);
				}
			}				
			
			if (mUpdatePeriod != -1 && mIsConnected) {
				long now = (new Date()).getTime();		
				
				if ((mChannelLastUpdate + mUpdatePeriod) <= now) {					
					URL url = new URL(mChannelUrl);
					Channel sameChannel = parser.handleChannel(url);
					List<Feed> downloadedFeeds = sameChannel.getItems();
					List<Feed> currentFeeds = mFeedAdapter.getFeedsByChannelId(mChannelId);
					List<Feed> newFeeds = this.getNewFeeds(downloadedFeeds, currentFeeds);
					if (newFeeds.size() > 0) {
						mFeedAdapter.addFeedsByChannelId(mChannelId, newFeeds);
					} 			
											
					mFeedAdapter.refreshChannelUpdateTime(mChannelId);
				} 
			}					
		} catch (Exception e) {
			this.ex = e;
		}
		
		return null;
	}
	
	@Override
	protected void onPostExecute(Void result) {
		if (ex != null) {
			this.closeProgressDialog();
			DialogFragment errorDialog = ErrorDialogFragment.newInstance(R.string.update_channel_error);
			errorDialog.show(mContext.getFragmentManager(), Utilities.ERROR_DIALOG_TAG);
		} else {
			this.closeProgressDialog();				
		}
	}
	
	private void closeProgressDialog(){
		ProgressDialogFragment fr = ((ProgressDialogFragment)mContext.getFragmentManager().
				findFragmentByTag(Utilities.PROGRESS_DIALOG_TAG));
		if (fr != null) {
			fr.dismiss();
		}	
	}
	
	private List<Feed> getNewFeeds(List<Feed> downloadedFeeds, List<Feed> currentFeeds){
		if (currentFeeds.size() == 0) {
			return downloadedFeeds;
		}
		
		Feed mostRecentFeed = currentFeeds.get(0);
		Date pubDate = mostRecentFeed.getPubDate();
		List<Feed> newFeeds = new ArrayList<Feed>();
		
		for (int i = 0; i < downloadedFeeds.size(); i++) {
			Feed newFeed = downloadedFeeds.get(i);
			Date newFeedDate = newFeed.getPubDate();
			if (!newFeedDate.after(pubDate)) {
				continue;
			}
			
			String guid = newFeed.getGuid();
			boolean isNew = true;
			for (int j = 0; j < currentFeeds.size(); j++) {
				Feed excistingFeed = currentFeeds.get(j);
				if (guid.equals(excistingFeed.getGuid())) {
					isNew = false;
					break;
				}
			}
			
			if (isNew) {
				newFeeds.add(newFeed);
			}
		}
		
		return newFeeds;
	}
}
